package scaladuct.l10n

import java.net.URL
import scala.None
import java.lang.String
import scaladuct.Property
import java.util.Locale
import util.logging.Logged

/**
 * <p>
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Dec 13, 2010
 * Time: 2:41:39 PM
 */

object ConfigPageMetaDataUtils {
}

abstract class SafeMetaData extends Logged {
  protected def metaData(): CommonMetaData

  def icon(defaultValue: URL): URL = try {
    metaData.icon.get
  }
  catch {
    case e: Exception => {
      debug(e.getMessage)
      defaultValue
    }
  }

  def description(defaultValue: String): String = try {
    metaData.description.get
  }
  catch {
    case e: Exception => {
      debug(e.getMessage)
      defaultValue
    }
  }

  def title(defaultValue: String): String = try {
    metaData.title.get
  }
  catch {
    case e: Exception => {
      debug(e.getMessage)
      defaultValue
    }
  }
}

sealed abstract class SafeConfigPageMetaData(wrapped: HasHintsMetaDataSource, locale: Locale) extends SafeMetaData {
  protected lazy val source = new CompleteHasHintsMetaDataSource(wrapped).configPageMetaData(locale)
}

case class PageMeta(wrapped: HasHintsMetaDataSource, locale: Locale) extends SafeConfigPageMetaData(wrapped, locale) {
  protected def metaData() = source.get.pageMeta.get
}

case class PropertyMeta[X](wrapped: HasHintsMetaDataSource, locale: Locale, property: Property[X]) extends SafeConfigPageMetaData(wrapped, locale) {
  protected def metaData() = source.get.propertyMeta(property).get
}

case class PropertyValueMeta[X](wrapped: HasHintsMetaDataSource, locale: Locale, property: Property[X]) extends SafeConfigPageMetaData(wrapped, locale) {
  protected def metaData() = source.get.propertyValueMeta(property).get
}

case class HintMeta[H](wrapped: HasHintsMetaDataSource, locale: Locale, hint: Property[H]) extends SafeConfigPageMetaData(wrapped, locale) {
  protected def metaData() = source.get.hintMeta(hint).get
}


class CompleteHasHintsMetaDataSource(wrapped: HasHintsMetaDataSource) extends HasHintsMetaDataSource {
  def configPageMetaData(locale: Locale): Some[CompleteHasHintsMetaData] = wrapped.configPageMetaData(locale) match {
    case Some(pm) => Some(new CompleteHasHintsMetaData(pm))
    case None => error("None unexpected")
  }

  class CompleteHasHintsMetaData(wrapped: HasHintsMetaData) extends HasHintsMetaData {
    def propertyValueMeta[X](property: Property[X]): Some[CompleteCommonMetaData] =
      wrapped.propertyValueMeta(property) match {
        case Some(pm) => Some(new CompleteCommonMetaData(pm))
        case None => error("None unexpected")
      }

    def propertyMeta[X](property: Property[X]): Some[CompleteCommonMetaData] = wrapped.propertyMeta(property) match {
      case Some(pm) => Some(new CompleteCommonMetaData(pm))
      case None => error("None unexpected")
    }

    def pageMeta: Some[CompleteCommonMetaData] = wrapped.pageMeta match {
      case Some(pm) => Some(new CompleteCommonMetaData(pm))
      case None => error("None unexpected")
    }

    def hintMeta[H](hint: Property[H]): Some[CompleteCommonMetaData] = wrapped.hintMeta(hint) match {
      case Some(pm) => Some(new CompleteCommonMetaData(pm))
      case None => error("None unexpected")
    }

    def pageLocale = wrapped.pageLocale

    class CompleteCommonMetaData(wrapped: CommonMetaData) extends CommonMetaData {
      def title: Some[String] = wrapped.title match {
        case Some(t) => Some(t)
        case None => error("None unexpected")
      }

      def description: Some[String] = wrapped.description match {
        case Some(d) => Some(d)
        case None => error("None unexpected")
      }

      def icon: Some[URL] = wrapped.icon match {
        case Some(i) => Some(i)
        case None => error("None unexpected")
      }
    }
  }

}